#include "stdafx.h"

#include "CodecManager.h"

///////////////////////////////////////Class Factory///////////////////////////////////////

CStreamBase* CCodecManager::CreateStream( unsigned long Class_ID )
{
	switch (Class_ID)
	{
		////////Base///////
	case CLASS_ID_CSTREAMBASE:
		////////Audio///////
	case CLASS_ID_CSTREAMFORCHANNEL:
		return NULL;
		break;
	case CLASS_ID_CAUDIOCODECSTREAM:
		{
			CAudioCodecStream* p = new CAudioCodecStream;
			p->p_event_manager=&event_manager;
			return (CStreamBase*)p;
		}
		break;
	case CLASS_ID_CAUDIOSTREAMENCODER:
		{
			CAudioCodecStream* p = new CAudioCodecStream;
			p->p_event_manager=&event_manager;
			p->Load(NULL,true);
			return (CStreamBase*)(new CAudioStreamEncoder(p));
		}
		break;
	case CLASS_ID_CAUDIOSTREAMDECODER:
		{
			CAudioCodecStream* p = new CAudioCodecStream;
			p->p_event_manager=&event_manager;
			p->Load(NULL,false);
			return (CStreamBase*)(new CAudioStreamDecoder(p));
		}
		break;
	case CLASS_ID_CAUDIOFILEENCODER:
		{
			CAudioCodecStream* p = new CAudioCodecStream;
			p->p_event_manager=&event_manager;
			return (CStreamBase*)(new CAudioFileEncoder(p));
		}
		break;
	case CLASS_ID_CAUDIOFILEDECODER:
		{
			CAudioCodecStream* p = new CAudioCodecStream;
			p->p_event_manager=&event_manager;
			return (CStreamBase*)(new CAudioFileDecoder(p));
		}
		break;
		////////Video///////
	case CLASS_ID_CVIDEOCODECSTREAM:
		{
			CVideoCodecStream* p = new CVideoCodecStream;
			p->p_event_manager=&event_manager;
			return (CStreamBase*)p;
		}
		break;
	case CLASS_ID_CVIDEOSTREAMENCODER:
		{
			CVideoCodecStream* p = new CVideoCodecStream;
			p->p_event_manager=&event_manager;
			return (CStreamBase*)(new CVideoStreamEncoder(p));
		}
		break;
	case CLASS_ID_CVIDEOSTREAMDECODER:
		{
			CVideoCodecStream* p = new CVideoCodecStream;
			p->p_event_manager=&event_manager;
			return (CStreamBase*)(new CVideoStreamDecoder(p));
		}
		break;
	case CLASS_ID_CVIDEOFILEENCODER:
		{
			CVideoCodecStream* p = new CVideoCodecStream;
			p->p_event_manager=&event_manager;
			return (CStreamBase*)(new CVideoFileEncoder(p));
		}
		break;
	case CLASS_ID_CVIDEOFILEDECODER:
		{
			CVideoCodecStream* p = new CVideoCodecStream;
			p->p_event_manager=&event_manager;
			return (CStreamBase*)(new CVideoFileDecoder(p));
		}
		break;
		////////Blend///////
	//case CLASS_ID_CBLENDCODECSTREAM:
		//{
			//return NULL;
		//}
		//break;
	case CLASS_ID_CBLENDSTREAMENCODER:
		{
			CAudioCodecStream* p = new CAudioCodecStream;
			p->Load(NULL,true);
			CVideoCodecStream* pv = new CVideoCodecStream;
			p->p_event_manager=&event_manager;
			pv->p_event_manager=&event_manager;
			return (CStreamBase*)(new CBlendStreamEncoder(p,pv));
		}
		break;
	case CLASS_ID_CBLENDSTREAMDECODER:
		{
			CAudioCodecStream* p = new CAudioCodecStream;
			p->Load(NULL,false);
			CVideoCodecStream* pv = new CVideoCodecStream;
			p->p_event_manager=&event_manager;
			pv->p_event_manager=&event_manager;
			return (CStreamBase*)(new CBlendStreamDecoder(p,pv));
		}
		break;
	case CLASS_ID_CBLENDFILEENCODER:
		{
			CAudioCodecStream* p = new CAudioCodecStream;
			CVideoCodecStream* pv = new CVideoCodecStream;
			p->p_event_manager=&event_manager;
			pv->p_event_manager=&event_manager;
			return (CStreamBase*)(new CBlendFileEncoder(p,pv));
		}
		break;
	case CLASS_ID_CBLENDFILEDECODER:
		{
			CAudioCodecStream* p = new CAudioCodecStream;
			CVideoCodecStream* pv = new CVideoCodecStream;
			p->p_event_manager=&event_manager;
			pv->p_event_manager=&event_manager;
			return (CStreamBase*)(new CBlendFileDecoder(p,pv));
		}
		break;
		////////Error///////
	default:
		return NULL;
	}
	return NULL;
}

void CCodecManager::ReleaseStream( CStreamBase* &p )
{
	unsigned long Class_Id=p->GetClassID();
	switch (Class_Id)
	{
		////////Base///////
	case CLASS_ID_CSTREAMBASE:
		////////Audio///////
	case CLASS_ID_CSTREAMFORCHANNEL:
		//Impossible
		break;
	case CLASS_ID_CAUDIOCODECSTREAM:
		delete p;
		p=NULL;
		break;
	case CLASS_ID_CAUDIOSTREAMENCODER:
		{
			CAudioCodecStream* ps=((CAudioStreamEncoder*)p)->getCodecStream();
			delete ps;
			delete p;
			p=NULL;
		}
		break;
	case CLASS_ID_CAUDIOSTREAMDECODER:
		{
			CAudioCodecStream* ps=((CAudioStreamDecoder*)p)->getCodecStream();
			delete ps;
			delete p;
			p=NULL;
		}
		break;
	case CLASS_ID_CAUDIOFILEENCODER:
		{
			CAudioCodecStream* ps=((CAudioFileEncoder*)p)->getCodecStream();
			delete ps;
			delete p;
			p=NULL;
		}
		break;
	case CLASS_ID_CAUDIOFILEDECODER:
		{
			CAudioCodecStream* ps=((CAudioFileDecoder*)p)->getCodecStream();
			delete ps;
			delete p;
			p=NULL;
		}
		break;
		////////Video///////
	case CLASS_ID_CVIDEOCODECSTREAM:
		delete p;
		p=NULL;
		break;
	case CLASS_ID_CVIDEOSTREAMENCODER:
		{
			CVideoCodecStream* ps=((CVideoStreamEncoder*)p)->getVideoCodecStream();
			delete ps;
			delete p;
			p=NULL;
		}
		break;
	case CLASS_ID_CVIDEOSTREAMDECODER:
		{
			CVideoCodecStream* ps=((CVideoStreamDecoder*)p)->getVideoCodecStream();
			delete ps;
			delete p;
			p=NULL;
		}
		break;
	case CLASS_ID_CVIDEOFILEENCODER:
		{
			CVideoCodecStream* ps=((CVideoFileEncoder*)p)->getVideoCodecStream();
			delete ps;
			delete p;
			p=NULL;
		}
		break;
	case CLASS_ID_CVIDEOFILEDECODER:
		{
			CVideoCodecStream* ps=((CVideoFileDecoder*)p)->getVideoCodecStream();
			delete ps;
			delete p;
			p=NULL;
		}
		break;
		////////Blend///////
	//case CLASS_ID_CBLENDCODECSTREAM:
		//not implement
		//break;
	case CLASS_ID_CBLENDSTREAMENCODER:
		{
			CAudioCodecStream* ps=((CBlendStreamEncoder*)p)->getCodecStream();
			CVideoCodecStream* psv=((CBlendStreamEncoder*)p)->getVideoCodecStream();
			delete ps;
			delete psv;
			delete p;
			p=NULL;
		}
		break;
	case CLASS_ID_CBLENDSTREAMDECODER:
		{
			CAudioCodecStream* ps=((CBlendStreamDecoder*)p)->getCodecStream();
			CVideoCodecStream* psv=((CBlendStreamDecoder*)p)->getVideoCodecStream();
			delete ps;
			delete psv;
			delete p;
			p=NULL;
		}
		break;
	case CLASS_ID_CBLENDFILEENCODER:
		{
			CAudioCodecStream* ps=((CBlendFileEncoder*)p)->getCodecStream();
			CVideoCodecStream* psv=((CBlendFileEncoder*)p)->getVideoCodecStream();
			delete ps;
			delete psv;
			delete p;
			p=NULL;
		}
		break;
	case CLASS_ID_CBLENDFILEDECODER:
		{
			CAudioCodecStream* ps=((CBlendFileDecoder*)p)->getCodecStream();
			CVideoCodecStream* psv=((CBlendFileDecoder*)p)->getVideoCodecStream();
			delete ps;
			delete psv;
			delete p;
			p=NULL;
		}
		break;
		////////Error///////
	default:
		break;
	}
}


///////////////////////////////////////Manager///////////////////////////////////////
CCodecManager::CCodecManager(void)
{
	avcodec_register_all();
	avdevice_register_all();
	av_register_all();
}

CCodecManager::~CCodecManager(void)
{
}
